package com.miyake.loveviewweb.client.viewer;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.appengine.api.datastore.Key;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.miyake.loveviewweb.client.DataServiceWrapper;
import com.miyake.loveviewweb.client.dialog.BasicDialog;
import com.miyake.loveviewweb.client.main.UiDataHandler;
import com.miyake.loveviewweb.client.plugin.InstalledPluginListCombo;
import com.miyake.loveviewweb.client.viewer.PluginDialogFactory.AnalyzerHandler;
import com.miyake.loveviewweb.client.viewer.PluginDialogFactory.ParserHandler;
import com.miyake.loveviewweb.shared.PluginType;
import com.miyake.loveviewweb.shared.model.ChartModel;
import com.miyake.loveviewweb.shared.model.DataModel;
import com.miyake.loveviewweb.shared.model.FolderModel;
import com.miyake.loveviewweb.shared.model.ValueModel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;

public class FolderViewer extends Viewer {
    private Map<CheckBox, DataModel> checkMap = new HashMap<CheckBox, DataModel>();
    
    @Override
    public void update(Key key) {
        if (DataModel.class.getName().contains(key.getKind())) {
            for (final DataModel dataModel : listWidget.getElements()) {
                if (dataModel.getKey().equals(key)) {
                    DataServiceWrapper.getInstance().getService().getData(key, false, new AsyncCallback<DataModel>() {
                        public void onFailure(Throwable caught) {
                        }

                        public void onSuccess(DataModel result) {
                            replace(dataModel, result);
                        }
                    });
                }
            }
        }
        else if (ChartModel.class.getName().contains(key.getKind())) {
            
            
            for (final DataModel dataModel : listWidget.getElements()) {
                if (dataModel.getKey().equals(key.getParent())) {
                    DataServiceWrapper.getInstance().getService().getData(key.getParent(), false, new AsyncCallback<DataModel>() {
                        public void onFailure(Throwable caught) {
                        }

                        public void onSuccess(DataModel result) {
                            replace(dataModel, result);
                        }
                    });
                }
            }
        }
        else {
            super.update(key);
        }
    }

    @Override
    protected int getLevel() {
        return 0;
    }

    AbstractListWidget<DataModel> listWidget;
    private UiDataHandler uiHandler;
    private FolderModel folderModel;
    private ListBox columnCombo;

    public FolderViewer(FolderModel folderModel, UiDataHandler uiHandler) {
        this.folderModel = folderModel;
        this.uiHandler = uiHandler;
    }

    @Override
    String getPageTitle() {
        return folderModel.getFolderName();
    }

    @Override
    Widget getContent() {
        VerticalPanel panel = new VerticalPanel();
        listWidget = new AbstractListWidget<DataModel>() {

            @Override
            protected
            Widget getWidget(DataModel element) {
                VerticalPanel panel = new VerticalPanel();
                CheckBox check = new CheckBox(element.getName());
                checkMap.put(check, element);
                panel.add(check);
                DataViewer dataViewer = new DataViewer(element, uiHandler);
                panel.add(dataViewer);
                dataViewer.update(element.getKey());
                return panel;
            }
            
        };
        panel.add(listWidget);
        listWidget.getGrid().setBorderWidth(1);
        listWidget.setColumns(columnCombo.getSelectedIndex()+1);
        DataServiceWrapper serviceWrapper = DataServiceWrapper.getInstance();
        serviceWrapper.getService().getDataList(serviceWrapper.getSelectedFolder().getKey(), false, new AsyncCallback<List<DataModel>>() {

            public void onFailure(Throwable caught) {
            }

            public void onSuccess(List<DataModel> result) {
                listWidget.setElements(stripSubData(result));
                listWidget.update();
            }
            
        });
        return panel;
    }

    protected List<DataModel> stripSubData(List<DataModel> result) {
        List<DataModel> ret = new ArrayList<DataModel>();
        for (DataModel dataModel : result) {
            if (dataModel.getSourceData() == null) {
                ret.add(dataModel);
            }
        }
        return ret;
    }

    @Override
    Widget getToolbar() {
        VerticalPanel vPanel = new VerticalPanel();
        vPanel.setWidth("100%");
        HorizontalPanel panel = new HorizontalPanel();
        vPanel.add(panel);
        panel.add(new HTML("Columns"));
        columnCombo = new ListBox();
        columnCombo.addItem("1");
        columnCombo.addItem("2");
        columnCombo.addItem("3");
        columnCombo.addItem("4");
        columnCombo.addChangeHandler(new ChangeHandler() {
            public void onChange(ChangeEvent event) {
                //listWidget.setColumns(columnCombo.getSelectedIndex()+1);
                folderModel.setColumns(columnCombo.getSelectedIndex()+1);
                DataServiceWrapper.getInstance().updateFolder(folderModel);
            }
        });
        panel.add(columnCombo);
        columnCombo.setSelectedIndex(folderModel.getColumns()-1);

        panel.add(getFilterPanel());
        
        final HorizontalPanel batchPanel = new HorizontalPanel();
        final CheckBox batchCheck = new CheckBox("Batch");
        panel.add(batchCheck);
        vPanel.add(batchPanel);
        batchCheck.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                batchPanel.setVisible(batchCheck.getValue()); 
                setCheckBoxVisible(batchCheck.getValue());
            }
        });
        batchPanel.setVisible(batchCheck.getValue());
        setCheckBoxVisible(batchCheck.getValue());
        
        final CheckBox checkAll = new CheckBox("All");
        batchPanel.add(checkAll);
        checkAll.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
            public void onValueChange(ValueChangeEvent<Boolean> event) {
                for (CheckBox check : checkMap.keySet()) {
                    check.setValue(checkAll.getValue());
                }
            }
        });
        
        batchPanel.add(new Button("Analyze", new ClickHandler() {
            public void onClick(ClickEvent event) {
                analyze();
            }
        }));
        batchPanel.add(new Button("Parse", new ClickHandler() {
            public void onClick(ClickEvent event) {
                parse();
            }
        }));
        batchPanel.add(new Button("Publish", new ClickHandler() {
            public void onClick(ClickEvent event) {
    
            }
        }));      
        return vPanel;
    }

    protected void analyze() {
        if (listWidget.getElements().size() > 0) {
            PluginDialogFactory.getInstance().createAnalyzer(new AnalyzerHandler() {
                public void onSelect(Key pluginKey, List<ValueModel> values, Map<String, String> data) {
                    for (DataModel dataModel : getSelectedData()) {
                        DataServiceWrapper.getInstance().analyze(pluginKey, values, data, dataModel.getKey());
                    }
                }
                
            }, listWidget.getElements().get(0));      
        }
    }

    protected void parse() {
        if (listWidget.getElements().size() > 0) {
            PluginDialogFactory.getInstance().createFileParser(new ParserHandler() {
                public void onSelect(Key pluginKey) {
                    for (DataModel dataModel : getSelectedData()) {
                        DataServiceWrapper.getInstance().parseFile(pluginKey, dataModel.getKey());                 
                    }
                }
            }, listWidget.getElements().get(0));
        }
    }

    protected List<DataModel> getSelectedData() {
        List<DataModel> ret = new ArrayList<DataModel>();
        for (CheckBox checkBox : checkMap.keySet()) {
            if (checkBox.getValue().equals(true)) {
                ret.add(checkMap.get(checkBox));
            }
        }
        return ret;
    }

    protected void setCheckBoxVisible(Boolean value) {
        for (CheckBox checkBox : this.checkMap.keySet()) {
            checkBox.setVisible(value);
        }
    }

    private Widget getFilterPanel() {
        HorizontalPanel p = new HorizontalPanel();
        p.setBorderWidth(1);
        
        TextBox text = new TextBox();
        p.add(new HTML("Filter:"));
        p.add(text);
        Button searchButton = new Button("Search");
        p.add(searchButton);
        searchButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                Window.alert("This function is not yet implemented");
            }
        });
        return p;
    }

    private void replace(final DataModel dataModel, DataModel result) {
        listWidget.replace(dataModel, result);
       // super.update(dataModel.getKey());
    }
}
